unit StockDataConsoleApp;

interface

uses      
  Forms, Sysutils, Windows, Classes,  
  BaseApp,
  BaseForm,
  db_dealitem,
  define_datasrc,
  define_dealItem,
  define_stockapp,
  define_StockDataApp,
  StockDataConsoleTask,
  StockDataTaskConsole,
  win.process;

type
  PConsoleAppData = ^TConsoleAppData;
  TConsoleAppData = record
    ConsoleForm: BaseForm.TfrmBase;
    StockTaskConsole: TStockTaskConsole;
    //RequestDownloadTask: TDownloadTask;
  end;

  TStockDataConsoleApp = class(BaseApp.TBaseAppAgent)
  protected                       
    fConsoleAppData: TConsoleAppData;
  public                  
    constructor Create(AHostApp: TBaseApp); override;
    destructor Destroy; override;     
    function Initialize: Boolean; override;
    procedure Run; override;

    function CreateAppCommandWindow: Boolean;
    property TaskConsole: TStockTaskConsole read fConsoleAppData.StockTaskConsole write fConsoleAppData.StockTaskConsole;
  end;
              
var
  G_StockDataConsoleApp: TStockDataConsoleApp = nil;
                     
implementation

uses
  windef_msg,
  {$IFDEF LOG}
  UtilsLog,
  {$ENDIF}
  //BaseStockApp,
  define_dealstore_file,
  BaseStockFormApp,  
  SDConsoleForm;
      
{$IFNDEF RELEASE}  
const
  LOGTAG = 'StockDataConsoleApp.pas';
{$ENDIF}

function AppCommandWndProcW(AWnd: HWND; AMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  tmpProcessTask: PDownloadProcessTask;
  tmpDownloadTask: PDownloadTask;
  tmpTaskDataType: TRT_TaskType;
  tmpStockCode: integer;
  tmpDataSrc: integer;
begin
  Result := 0;
  case AMsg of
    WM_AppStart: begin
    end;
    WM_AppRequestEnd: begin
      if nil <> GlobalBaseStockApp then
      begin
        GlobalBaseStockApp.Terminate;
      end;
    end;
    WM_Console_Command_Download: begin
       tmpStockCode := 0;
       tmpDataSrc := 0;
       tmpTaskDataType := taskUnknown;
       if 0 = wParam then
       begin
         exit;
       end;
       if 1 = wParam then
       begin
         tmpDownloadTask := PDownloadTask(lParam);
         tmpTaskDataType := tmpDownloadTask.TaskDataType;  
         tmpDataSrc := GetDealDataSourceCode(tmpDownloadTask.TaskDataSrc);
         tmpStockCode := tmpDownloadTask.TaskDealItemCode;
       end;
       if 2 = wParam then
       begin
         tmpProcessTask := PDownloadProcessTask(lparam);
         tmpDownloadTask := tmpProcessTask.OwnerTask;
         if nil <> tmpDownloadTask then
         begin
           tmpTaskDataType := tmpDownloadTask.TaskDataType;
           tmpDataSrc := GetDealDataSourceCode(tmpDownloadTask.TaskDataSrc);
         end;
         if nil <> tmpProcessTask.DealItem then
           tmpStockCode := tmpProcessTask.DealItem.iCode;
       end;
       if nil <> G_StockDataConsoleApp then
       begin
         if (nil <> G_StockDataConsoleApp.TaskConsole) then
         begin
           tmpDownloadTask := G_StockDataConsoleApp.TaskConsole.CheckOutDownloadTask(tmpTaskDataType, GetDealDataSource(tmpDataSrc), tmpStockCode);
           if TaskAssigned = tmpDownloadTask.TaskStatus then
           begin
             G_StockDataConsoleApp.TaskConsole.RunTask(tmpDownloadTask);
           end;
         end;
       end;
    end;
    WM_RequestHostCommandWnd: begin
      tmpProcessTask := G_StockDataConsoleApp.TaskConsole.GetDownloadTaskByProcessID(wParam);
      if nil <> tmpProcessTask then
      begin
        Result := tmpProcessTask.DownloadProcess.HostCmdWnd.CmdWndHandle;
      end;
    end;
    WM_AppNotifyShutdownMachine: begin
    end;
    else    
      Result := DefWindowProcW(AWnd, AMsg, wParam, lParam);
      //Result :=
      //BusinessCommandWndProcA(nil, AWnd, AMsg, wParam, lParam);
  end;
end;
                
{ TStockDataConsoleApp }

constructor TStockDataConsoleApp.Create(AHostApp: TBaseApp);
begin
  inherited;
  G_StockDataConsoleApp := Self;
  FillChar(fConsoleAppData, SizeOf(fConsoleAppData), 0);
  AHostApp.AppAgent := Self;
end;
           
destructor TStockDataConsoleApp.Destroy;
begin
  if G_StockDataConsoleApp = Self then
  begin
    G_StockDataConsoleApp := nil;
  end;
  if nil <> fConsoleAppData.StockTaskConsole then
  begin
    FreeAndNil(fConsoleAppData.StockTaskConsole);
  end;
  inherited;
end;

function TStockDataConsoleApp.Initialize: Boolean;
begin
  Result := inherited Initialize;     
  {$IFDEF LOG}
  LOG(LOGTAG, 'TStockDataConsoleApp.Initialize');
  {$ENDIF}
  if Result then
  begin
    Application.Initialize;  
    Result := CreateAppCommandWindow;
    if nil = fConsoleAppData.StockTaskConsole then
    begin
      fConsoleAppData.StockTaskConsole := TStockTaskConsole.Create;
      fConsoleAppData.StockTaskConsole.StockItemDB := TBaseStockApp(fBaseAppAgentData.HostApp).StockItemDB;
      fConsoleAppData.StockTaskConsole.StockIndexDB := TBaseStockApp(fBaseAppAgentData.HostApp).StockIndexDB;
      fConsoleAppData.StockTaskConsole.AppWindow := TBaseStockApp(fBaseAppAgentData.HostApp).AppWindow;      
    end;
  end;                    
  {$IFDEF LOG}
  LOG(LOGTAG, 'TStockDataConsoleApp.Initialize end');
  {$ENDIF}
end;

procedure TStockDataConsoleApp.Run;
begin            
  {$IFDEF LOG}                    
  LOG(LOGTAG, 'TStockDataConsoleApp.Run');
  {$ENDIF}
  Application.CreateForm(TfrmSDConsole, fConsoleAppData.ConsoleForm);
  fConsoleAppData.ConsoleForm.Initialize(fBaseAppAgentData.HostApp); 
  {$IFDEF LOG}
  LOG(LOGTAG, 'TStockDataConsoleApp.Run Application');
  {$ENDIF}
  Application.Run;
end;

               
function TStockDataConsoleApp.CreateAppCommandWindow: Boolean;
var
  tmpRegWinClass: TWndClassW;
  tmpGetWinClass: TWndClassW;
  tmpIsReged: Boolean;
begin
  Result := false;          
  FillChar(tmpRegWinClass, SizeOf(tmpRegWinClass), 0);
  tmpRegWinClass.hInstance := HInstance;
  tmpRegWinClass.lpfnWndProc := @AppCommandWndProcW;
  tmpRegWinClass.lpszClassName := AppCmdWndClassName_StockDataDownloader_Console;
  tmpIsReged := GetClassInfoW(HInstance, tmpRegWinClass.lpszClassName, tmpGetWinClass);
  if tmpIsReged then
  begin
    if (tmpGetWinClass.lpfnWndProc <> tmpRegWinClass.lpfnWndProc) then
    begin                           
      UnregisterClassW(tmpRegWinClass.lpszClassName, HInstance);
      tmpIsReged := false;
    end;
  end;
  if not tmpIsReged then
  begin
    if 0 = RegisterClassW(tmpRegWinClass) then
      exit;
  end;
  TBaseStockApp(fBaseAppAgentData.HostApp).AppWindow := CreateWindowExW(
    WS_EX_TOOLWINDOW
    //or WS_EX_APPWINDOW
    //or WS_EX_TOPMOST
    ,
    tmpRegWinClass.lpszClassName,
    '', WS_POPUP {+ 0},
    0, 0, 0, 0,
    HWND_MESSAGE, 0, HInstance, nil);
  Result := Windows.IsWindow(TBaseStockApp(fBaseAppAgentData.HostApp).AppWindow);
end;

end.
